﻿using SuperX.Common;
using SuperX.Common.Log;
using SuperX.DataService.Abstract;
using HslCommunication.Core;
using NPOI.SS.Formula.Functions;
using NPOI.SS.Formula.PTG;
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;

namespace SuperX.DataService.Helper
{
    public class ByteTransformConverter
    {
        /// <summary>
        ///
        /// </summary>
        /// <param name="tag">tag</param>
        /// <param name="ByteTransform">转换器</param>
        /// <param name="dataType">数据类型</param>
        /// <param name="rcvBytes">接收的byte数组</param>
        /// <param name="offset">byte偏移</param>
        /// <param name="stringsize">字符串读取长度</param>
        /// <param name="rcvBools">接收的布尔量数组</param>
        /// <param name="bitOffset">位偏移</param>
        /// <param name="TransBool">布尔量转换方法</param>
        public static void UpdateTagValue(IIOTag tag, IByteTransform ByteTransform, DataType dataType, byte[] rcvBytes, int offset, int stringsize, bool[] rcvBools, int bitOffset, FuncEx<bool[], byte[], int, bool, bool> TransBool)
        {
            try
            {
                if (dataType == DataType.BOOL)
                {
                    var res = TransBool(rcvBools, rcvBytes, bitOffset, out var convertRes);
                    if (!convertRes) return;
                    UpdateTagValue(tag, res);
                }
                else
                {
                    if (rcvBytes == null) return;
                    switch (dataType)
                    {
                        case DataType.BYTE:
                            UpdateTagValue(tag, ByteTransform.TransByte(rcvBytes, offset));
                            break;

                        case DataType.SHORT:
                            UpdateTagValue(tag, ByteTransform.TransInt16(rcvBytes, offset));
                            break;

                        case DataType.INT:
                            UpdateTagValue(tag, ByteTransform.TransInt32(rcvBytes, offset));
                            break;

                        case DataType.DWORD:
                            UpdateTagValue(tag, ByteTransform.TransUInt32(rcvBytes, offset));
                            break;

                        case DataType.FLOAT:
                            UpdateTagValue(tag, ByteTransform.TransSingle(rcvBytes, offset));
                            break;

                        case DataType.WORD:
                            UpdateTagValue(tag, ByteTransform.TransUInt16(rcvBytes, offset));
                            break;

                        case DataType.STR:
                            UpdateTagValue(tag, ByteTransform.TransString(rcvBytes, offset, stringsize, Encoding.UTF8));
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Warn($"{tag.FullName},类型{dataType.ToString()}，转换错误,错误信息:{ex.Message}");
            }
        }

        public static byte[] SwapPairs(byte[] sourceArray)
        {
            int length = sourceArray.Length;
            byte[] destinationArray = new byte[sourceArray.Length];

            // 复制源数组到目标数组
            Array.Copy(sourceArray, destinationArray, sourceArray.Length);

            // 处理偶数长度的部分
            for (int i = 0; i < length - 1; i += 2)
            {
                byte temp = sourceArray[i];
                destinationArray[i] = sourceArray[i + 1];
                destinationArray[i + 1] = temp;
            }
            return destinationArray;
        }

        private static void UpdateTagValue(IIOTag tag, object value)
        {
            tag.UpdateIoTagValue(value, QUALITIES.OK, DateTime.Now);
            tag.Quality = QUALITIES.OK;
        }

        public delegate TResult FuncEx<in T1, in T2, in T3, T4, out TResult>(T1 t1, T2 t2, T3 t3, out T4 t4);
    }
}